#ifndef ZG_TUNNEL_H
#define ZG_TUNNEL_H

#include "thread"
#include "iostream"
#include "fstream"
#include "vector"
#include "Queue.h"
#include "Event.h"
using std::placeholders::_1;
using std::placeholders::_2;
using std::thread;
namespace zg_util{
    class Tunnel{
    public:
        Tunnel(const std::string tunnelname="") :_tunnel_name(tunnelname),is_start(false) {}
        Tunnel *Add(Tunnel *next);
        Tunnel *Link(Tunnel *next);
        std::string &GetTunnelName(){return _tunnel_name;}
        virtual void Start();
        virtual void Stop();
        const std::vector<Tunnel*> &NextTunnels() const {return _nexts;}
        Queue _queue;
    protected:
        virtual void handler()=0;
        bool is_start;
        void TunnelLog(const std::string info);
    private:
        void safe_run();
        std::vector<Tunnel*> _nexts;
        std::string _tunnel_name;
        thread _td;
        Event _stop_ev;
    };

    class TunnelExtend : public Tunnel{
    public:
        TunnelExtend(const std::string tunnelname,int thread_count):Tunnel(tunnelname),_td_count(thread_count){}
        virtual void Start();
        virtual void Stop();
    private:
        void safe_run(Event *ev);
        std::vector<thread> _tds;
        std::vector<Event> _evs;
        int _td_count;
    };
}

#endif
